﻿using System.Collections.Generic;
using System.Text;

namespace Universe.MediaProbe
{
    using System;
    using System.Collections.ObjectModel;

    public class ProbeReportDigest : Collection<ProbeReportDigest.Digest>
    {
        public static ProbeReportDigest GetWaiting(string fileName)
        {
            ProbeReportDigest ret = new ProbeReportDigest();
            ret.Add(new Digest
            {
                Kind = StreamKind.Info,
                Caption = "Examining is in progress",
                Value = "Info about " + fileName + " is loading..."
            });

            return ret;
        }

        public static ProbeReportDigest GetFail(string fileName, Exception ex)
        {
            ProbeReportDigest ret = new ProbeReportDigest();
            ret.Add(new Digest
            {
                Kind = StreamKind.Info,
                Caption = "Probe is unavailable for file " + fileName,
                Value = "Error: " + ex.Message,
            });

            return ret;
        }

        
        public static ProbeReportDigest Build(ProbeReport report)
        {
            ProbeReportDigest ret = new ProbeReportDigest();

            if (report.Error != null)
            {
                ret.Add(new Digest
                {
                    Kind = StreamKind.Info,
                    Caption = "Error :( File is " + report.FullName,
                    Value = report.Error.Number + ": " + report.Error.Description
                });

                return ret;
            }
            
            ret.Add(new Digest
            {
                Kind = StreamKind.Info,
                Caption = "General",
                Value = FormatDuration(report.Duration) + ", " + report.Format,
                Width = 100,
            });

            if (report.HasVideo)
            {
                var video = report.Videos[0];
                ret.Add(new Digest
                {
                    Kind = StreamKind.Video,
                    Caption = "Video #" + video.IdStream,
                    Value = string.Format("{0}*{1}, {2}, {3:f3} fps", video.Width, video.Height, video.Codec, video.FrameRate),
                    Width = 200,
                    IdStream = video.IdStream,
                });
            }

            if (report.HasAudio)
            {
                foreach (var audio in report.Audios)
                {
                    ret.Add(new Digest
                    {
                        Kind = StreamKind.Audio,
                        Caption = "Audio #" + audio.IdStream,
                        Value = SmartJoin(", ", audio.Language, audio.Channels + "ch", audio.Codec),
                        Width = 120,
                        IdStream = audio.IdStream,
                    });
                }
            }

            if (report.HasSubTitles)
            {
                foreach (var sub in report.Subs)
                {
                    ret.Add(new Digest
                    {
                        Kind = StreamKind.Sub,
                        Caption = "Sub #" + sub.IdStream,
                        Value = string.Format("{0}, {1}", sub.Language, sub.Codec),
                        Width = 80,
                        IdStream = sub.IdStream,
                    });
                }
            }

            return ret;
        }

        static string SmartJoin(string separator, IEnumerable<string> strings)
        {
            StringBuilder ret = new StringBuilder();
            foreach (var s in strings)
                if (!string.IsNullOrEmpty(s))
                    ret.Append(ret.Length == 0 ? "" : separator).Append(s);

            return ret.ToString();
        }

        static string SmartJoin(string separator, params string[] strings)
        {
            return SmartJoin(separator, (IEnumerable<string>)strings);
        }

        static string FormatDuration(decimal arg)
        {
            return new DateTime(0).AddSeconds((double) arg).ToString("HH:mm:ss");
        }


        public class Digest
        {
            public StreamKind Kind { get; set; }
            public string Caption { get; set; }
            public string Value { get; set; }
            public int Width { get; set; }
            public int? IdStream { get; set; }
        }

        public enum StreamKind
        {
            Info,
            Video,
            Audio,
            Sub
        }
    }
}
